import datetime
import time

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By

from libs import config
from libs.action import WebDriverAction
from libs.game import Game
from libs.image import ImageTool
from libs.log import Log
from libs.movement import Movement
from libs.trade_helper import TradeHelper, TaskItem
from libs.window import AdsWindow
from libs.task_helper import TaskHelper


def make_screw():
    ac = ActionChains(driver)
    screw_name = 'Copperite Screw'
    screw_qty = game.get_backpack_qty(screw_name)
    if screw_qty > 50:
        return
    movement.keep_move_right(1.8)
    # 检查是否有工作台,是否有Copperite Ore
    station_image = 'metalworking.png'
    stations = image_tool.find_all_targets(station_image)
    kit_name = 'Basic Metalworking Kit'
    buy_items = {}
    if len(stations) == 0:
        has_qty = game.get_backpack_qty(kit_name)
        if has_qty < 4:
            buy_items[kit_name] = 4 - has_qty
    ore_name = 'Copperite Ore'
    ore_qty = game.get_backpack_qty(ore_name)
    if ore_qty < 20 and ore_qty + screw_qty < 98:
        buy_items[ore_name] = 98 - ore_qty - screw_qty
    if len(buy_items) > 0:
        trade_helper.goto_buy_position()
        filter_input = trade_helper.open_market_buy()
        for buy_name in buy_items:
            buy_qty = buy_items.get(buy_name)
            trade_helper.market_buy_item(filter_input, buy_name, buy_qty)
        action.escape()
        action.escape()
        action.goto_task_board()
        movement.keep_move_right(1.8)
        game.get_backpack()
    if len(stations) == 0:
        right_door_image = 'task_board_right_door.png'
        (door_x, door_y) = image_tool.find_target(right_door_image)
        kit_index, _ = game.get_backpack_index_and_qty(kit_name)
        game.use_backpack_item(kit_index)
        ac.reset_actions()
        ac.move_by_offset(door_x + 267, door_y + 253).click().perform()
        time.sleep(1)
        ac.move_by_offset(190, 0).click().perform()
        time.sleep(1)
        ac.move_by_offset(0, 128).click().perform()
        time.sleep(1)
        ac.move_by_offset(-190, 0).click().perform()
        time.sleep(1)
        stations = image_tool.find_all_targets(station_image)
    can_craft = True
    for _ in range(5):
        if not can_craft:
            break
        if game.get_energy() < 30:
            game.spec_drink_wine(1000)
            if game.get_energy() < 30:
                break
            action.goto_task_board()
            movement.keep_move_right(1.8)
            stations = image_tool.find_all_targets(station_image)

        for (x, y) in stations:
            if not can_craft:
                break
            action.click_by_offset(x, y)
            opt = action.find_element(By.XPATH, f"//span[text()='{screw_name}']", screw_name, 3)
            if opt is None:
                action.escape()
                time.sleep(1)
                action.click()
                opt = action.find_element(By.XPATH, f"//span[text()='{screw_name}']", screw_name, 10)
            opt.click()
            time.sleep(1)
            for _ in range(10):
                craft_button = action.find_element(By.CLASS_NAME, "Crafting_craftingButton__Qd6Ke", 'CraftButton', 2)
                if craft_button.text == 'Collect':
                    if craft_button.is_enabled():
                        craft_button.click()
                        time.sleep(3)
                        continue
                if craft_button.text == 'Create':
                    if craft_button.is_enabled():
                        craft_button.click()
                        time.sleep(1)
                    else:
                        can_craft = False
                    action.escape()
                    action.escape()
                    break
                time.sleep(1)
    movement.keep_move_left(1.8)

if __name__ == "__main__":
    parser = TaskHelper.default_args_parser('Trade')
    args = parser.parse_args()
    task_helper = TaskHelper.from_args(args)

    user_id = args.user_id
    log = Log(user_id)
    # 启动窗口
    driver = AdsWindow(user_id).open(False)
    action = WebDriverAction(driver)
    movement = Movement(driver)
    image_tool = ImageTool(driver)
    game = Game(driver, user_id)
    trade_helper = TradeHelper(driver, user_id)
    log.info(f"trade start")

    # 进入游戏/
    game.enter_game(user_id)

    # 收邮件
    game.collect_mail()
    game.snapshot(user_id, 'after_collect_mail')

    total_deliver = 0
    one_task_rounds = 0
    fail_times = 0

    for task_round in range(30):
        try:
            action.escape()
            action.escape()
            game.enter_game(user_id)
            game.snapshot(user_id, 'loop start', include_skills=False)
            # 1. 查看任务
            action.goto_task_board()
            port_count = trade_helper.check_tasks()
            action.escape()
            # 2. 商店购买
            trade_helper.goto_buy_position()
            coin_before = game.get_coin()
            p_before = game.get_p()
            if config.can_trade(user_id):
                trade_helper.buy()
            # 3. 交任务
            action.goto_task_board()
            deliver_count = trade_helper.deliver()
            time.sleep(1)
            coin_spent = coin_before - game.get_coin()
            p_received = game.get_p() - p_before
            total_deliver += deliver_count
            log.info(f"round {task_round}, deliver {deliver_count}/{port_count}, left coin {game.get_coin()}")
            if deliver_count <= 1:
                limit = trade_helper.trade_config.get('one_task_rounds', 1)
                one_task_rounds += 1
                if one_task_rounds >= limit:
                    log.info(f"trade finish, loop={task_round}, deliver_count={total_deliver}")
                    break
            else:
                one_task_rounds = 0
            need_buy = False
            for index in trade_helper.tasks:
                task: TaskItem = trade_helper.tasks.get(index)
                # 有未获取到价格的任务
                if task.is_on_sale() and task.price is None:
                    need_buy = True
            if not need_buy and len(trade_helper.tasks) == port_count:
                log.info(f"trade finish, loop={task_round}, deliver_count={total_deliver}")
                break
            log.debug('goto make screw')
            start = datetime.datetime.now()
            make_screw()
            time_left = 120 - (datetime.datetime.now() - start).seconds
            if time_left > 0:
                log.debug(f'wait {time_left} seconds')
                time.sleep(time_left)
        except Exception as e:
            fail_times += 1
            log.info('error occurred')
            print(e)
            if fail_times > 3:
                break
            else:
                continue

    time.sleep(5)

    try:
        # 去睡觉
        movement.keep_move_right(3.5)
        bed_loc = image_tool.find_target('bed.png')
        if bed_loc:
            bed_x, bed_y = bed_loc
            action.move_by_offset(bed_x - 80, bed_y - 40)
            for _ in range(4):
                target = action.find_element(By.CLASS_NAME, 'LookAtBubble_lookAtBubble___pd4a', 'LookAtBubble', 1)
                if target is None:
                    time.sleep(0.5)
                    continue
                elif target.text == 'Sleep to Gain Energy':
                    log.info('sleep')
                    action.click()
                    time.sleep(60)
                    break
                else:
                    continue

        action.escape()
        action.escape()
        time.sleep(10)
        game.snapshot(user_id, 'after_trade')
    except:
        pass

    if fail_times > 3:
        task_helper.task_fail()
        task_helper.trade(retry=True)
    else:
        # 24小时后再次执行
        task_helper.task_success()
        task_helper.trade(delay_seconds=60 * 60 * 24)
